package com.unswift.window;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.Timer;

import com.unswift.QuickApplication;
import com.unswift.constant.ActionConstant;
import com.unswift.constant.ButtonConstant;
import com.unswift.constant.QuickConstant;
import com.unswift.utils.DbSession;
import com.unswift.utils.ObjectUtils;
import com.unswift.utils.StringUtils;
import com.unswift.utils.SystemUtils;
import com.unswift.utils.ThreadUtils;
import com.unswift.utils.DbSession.FindDataBack;
import com.unswift.window.editor.Editor;
import com.unswift.window.extend.Attribute;
import com.unswift.window.factory.ButtonFactory;
import com.unswift.window.factory.FileChooseFactory;
import com.unswift.window.factory.FormFactory;
import com.unswift.window.factory.IconFactory;
import com.unswift.window.factory.LabelFactory;
import com.unswift.window.factory.MessageFactory;
import com.unswift.window.factory.PanelFactory;
import com.unswift.window.factory.ScrollFactory;
import com.unswift.window.factory.SplitFactory;
import com.unswift.window.factory.TabFactory;
import com.unswift.window.factory.TableFactory;
import com.unswift.window.listener.InputKeyListener;
import com.unswift.window.listener.MainWindowListener;
import com.unswift.window.listener.TabChangeListener;
import com.unswift.window.table.Table;
import com.unswift.window.table.TableTitle;
import com.unswift.window.timer.MemoryTimerTask;

@SuppressWarnings("serial")
public class MainWindow extends JFrame{

	private int width, height;
	
	public MainWindow() {
		setBounds();
		setImageIcon();
		this.setTitle(QuickApplication.getConfig(QuickConstant.CONF_APPLICATION_NAME));
		this.initFrame();
		this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		this.addWindowListener(new MainWindowListener());
		this.setVisible(true);
	}
	
	private void setBounds() {
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(this.getGraphicsConfiguration());
		int taskBarHeight = screenInsets.bottom;
		width=screenSize.width;
		height=screenSize.height;
		height-=taskBarHeight;
		this.setBounds(0, 0, width, height);
	}
	
	private void setImageIcon(){
		ImageIcon icon=IconFactory.createIcon("images/logo.png");
		this.setIconImage(icon.getImage());
	}
	
	private void initFrame(){
		JPanel root = (JPanel)this.getContentPane();
		JPanel main=PanelFactory.create(Color.WHITE, null, new BorderLayout());
		JPanel frame=PanelFactory.create(Color.WHITE, null, new BorderLayout());
		JTabbedPane tabs=TabFactory.createTab(BorderFactory.createMatteBorder(1, 0, 0, 0, new Color(220, 220, 220)));
		
		JPanel projectFrame=PanelFactory.create(Color.WHITE, null, new BorderLayout());
		initProjectFrame(projectFrame);
		tabs.addTab("创建项目 ", IconFactory.createIcon("images/icon/project-icon.png"), projectFrame);
		
		JPanel serverFrame=PanelFactory.create(Color.WHITE, null, new BorderLayout());
		initServerFrame(serverFrame);
		tabs.addTab("创建微服务 ", IconFactory.createIcon("images/icon/cloud-icon.png"), serverFrame);
		
		JPanel moduleFrame=PanelFactory.create(Color.WHITE, null, new BorderLayout());
		initCreateModuleFrame(moduleFrame);
		tabs.addTab("创建模块 ", IconFactory.createIcon("images/icon/module-icon.png"), moduleFrame);
		
		JPanel addFieldFrame=PanelFactory.create(Color.WHITE, null, new BorderLayout());
		initAddFieldFrame(addFieldFrame);
		tabs.addTab("增加列", IconFactory.createIcon("images/icon/add-field-icon.png"), addFieldFrame);
		
		JPanel dropFieldFrame=PanelFactory.create(Color.WHITE, null, new BorderLayout());
		initDropFieldFrame(dropFieldFrame);
		tabs.addTab("删除字段", IconFactory.createIcon("images/icon/delete-field-icon.png"), dropFieldFrame);
		
		tabs.addChangeListener(new TabChangeListener());
		frame.add(tabs);
		JPanel bottom=PanelFactory.create(null, null, new BorderLayout());
		initBottom(bottom);
		main.add(frame, BorderLayout.CENTER);
		main.add(bottom, BorderLayout.SOUTH);
		root.add(main);
	}
	
	private void initProjectFrame(JPanel projectFrame){
		JPanel projectMain=PanelFactory.create(null, null, new BorderLayout());
		projectFrame.add(projectMain, BorderLayout.CENTER);
		
		JPanel projectPath;
		JTextField projectName;
		JTextField projectDomain;
		JTextField projectDescribe;
		JComboBox<String> developTools;
		JPanel webFrameworks;
		JTextField nacosServer;
		JTextField nacosNamespace;
		projectPath=FormFactory.createFormFile(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, FileChooseFactory.getDefaultFile().getAbsolutePath()+"\\")
				.put(Attribute.ATTRIBUTE_FORM_EDITABLE, false)
				.put(Attribute.ATTRIBUTE_FILECHOOSE_TYPE, JFileChooser.DIRECTORIES_ONLY)
				.put(Attribute.ATTRIBUTE_FILECHOOSE_ENABLED, false)
				.put(Attribute.ATTRIBUTE_FORM_ACTION, ButtonConstant.ACTION_CREATE_PROJECT_PATH_FILE_SELECT)
		);
		projectDomain=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_DOMAIN), ""))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "com.xxx.cloud")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		);
		JPanel form=FormFactory.create(Color.WHITE, null, 2, 9, null);
		FormFactory.addRow(form, 0, "项目名称：", projectName=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, "")
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "只能输入a-z,0-9,-字符，不允许输入其它字符")
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				.put(Attribute.ATTRIBUTE_FORM_KEY_LISTENER, new InputKeyListener(ActionConstant.ACTION_PROJECT_NAME, projectPath.getComponent(0), projectDomain))
			), null, null);
		FormFactory.addRow(form, 1, "项目域名：", projectDomain, null, null);
		FormFactory.addRow(form, 2, "项目存放目录：", projectPath, null, null);
		FormFactory.addRow(form, 3, "项目描述：", projectDescribe=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, "")
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
			), null, null);
		FormFactory.addRow(form, 4, "开发工具：", developTools=FormFactory.createFormSelect(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_SELECT_OPTIONS, QuickApplication.getDevelopTools())
		), null, null);
		FormFactory.addRow(form, 5, "初始服务：", FormFactory.createFormCheck(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, QuickApplication.getProjectServers())
			.put(Attribute.ATTRIBUTE_FORM_BGCOLOR, Color.WHITE)
			.put(Attribute.ATTRIBUTE_FORM_ENABLED, false)
			.put(Attribute.ATTRIBUTE_FORM_SELECT, QuickApplication.getProjectServers())
		), null, null);
		FormFactory.addRow(form, 6, "前端架构：", webFrameworks=FormFactory.createFormRadio(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, QuickApplication.getProjectWebFrameworks())
			.put(Attribute.ATTRIBUTE_FORM_BGCOLOR, Color.WHITE)
			.put(Attribute.ATTRIBUTE_FORM_SELECT, "layui")
		), null, null);
		
		FormFactory.addRow(form, 7, "Nacos服务器：", nacosServer=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_NACOS_SERVER), ""))
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "127.0.0.1:8848")
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		FormFactory.addRow(form, 8, "Nacos命名空间：", nacosNamespace=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_NACOS_NAMESPACE), ""))
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "cloud")
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		
		projectMain.add(ScrollFactory.addScroll(form, null, null), BorderLayout.CENTER);
		QuickApplication.cache.setHash("project", "projectPath", projectPath.getComponent(0));
		QuickApplication.cache.setHash("project", "projectName", projectName);
		QuickApplication.cache.setHash("project", "projectDomain", projectDomain);
		QuickApplication.cache.setHash("project", "projectDescribe", projectDescribe);
		QuickApplication.cache.setHash("project", "developTools", developTools);
		QuickApplication.cache.setHash("project", "webFrameworks", webFrameworks.getComponents());
		QuickApplication.cache.setHash("project", "nacosServer", nacosServer);
		QuickApplication.cache.setHash("project", "nacosNamespace", nacosNamespace);
		
		JPanel buttonPanel=PanelFactory.create(null, null, new FlowLayout(FlowLayout.CENTER));
		buttonPanel.add(ButtonFactory.createButton(Attribute.create()
			.put(Attribute.ATTRIBUTE_BUTTON_NAME, "生成项目")
			.put(Attribute.ATTRIBUTE_BUTTON_ORIGINAL, true)
			.put(Attribute.ATTRIBUTE_BUTTON_OPAQUE, true)
			.put(Attribute.ATTRIBUTE_BUTTON_PADDING, null)
			.put(Attribute.ATTRIBUTE_BUTTON_MARGIN, null)
			.put(Attribute.ATTRIBUTE_BUTTON_ACTION, ButtonConstant.ACTION_CREATE_PROJECT)
		));
		projectMain.add(buttonPanel, BorderLayout.SOUTH);
		
		JPanel describePanel=PanelFactory.create(null, null, new BorderLayout());
		Editor projectDevelopDescribe=FormFactory.createFormArea(
				Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, QuickApplication.getCreateProjectDescribe())
			.put(Attribute.ATTRIBUTE_FORM_EDITABLE, false)
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
			.put(Attribute.ATTRIBUTE_FORM_EDITOR_LINES, false)
		);
		describePanel.add(ScrollFactory.addScroll(projectDevelopDescribe, null, null));
		
		JSplitPane split = SplitFactory.create(JSplitPane.VERTICAL_SPLIT, projectMain, describePanel, 450, 2, false);
		projectFrame.add(split);
	}
	
	private void initServerFrame(JPanel serverFrame){
		JPanel serverMain=PanelFactory.create(null, null, new BorderLayout());
		serverFrame.add(serverMain, BorderLayout.CENTER);
		
		JPanel projectPath;
		JTextField projectDomain;
		JTextField nacosServer;
		JTextField nacosNamespace;
		JTextField serverFileName;
		JTextField serverName;
		JTextField serverPort;
		JTextField serverComment;
		JTextField username;
		projectPath=FormFactory.createFormFile(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, FileChooseFactory.getDefaultFile().getAbsolutePath()+"\\")
				.put(Attribute.ATTRIBUTE_FORM_EDITABLE, false)
				.put(Attribute.ATTRIBUTE_FILECHOOSE_TYPE, JFileChooser.DIRECTORIES_ONLY)
				.put(Attribute.ATTRIBUTE_FILECHOOSE_ENABLED, false)
				.put(Attribute.ATTRIBUTE_FORM_ACTION, ButtonConstant.ACTION_CREATE_PROJECT_PATH_FILE_SELECT)
		);
		projectDomain=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_DOMAIN), ""))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "com.xxx.cloud")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		);
		serverPort=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_SERVER_PORT), ""))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "只能输入数字")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		);
		
		JPanel form=FormFactory.create(Color.WHITE, null, 2, 9, null);
		FormFactory.addRow(form, 0, "项目路径：", projectPath, null, null);
		FormFactory.addRow(form, 1, "域名：", projectDomain, null, null);
		
		FormFactory.addRow(form, 2, "Nacos服务器：", nacosServer=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_NACOS_SERVER), ""))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "127.0.0.1:8848")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		FormFactory.addRow(form, 3, "Nacos命名空间：", nacosNamespace=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_NACOS_NAMESPACE), ""))
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "cloud")
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		
		serverName=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_SERVER_NAME), ""))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "只能输入a-z,0-9,-字符，不允许输入其它字符")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
			.put(Attribute.ATTRIBUTE_FORM_COLUMNS, 22)
		);
		
		FormFactory.addRow(form, 4, "微服务项目名：", serverFileName=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_SERVER_FILE_NAME), ""))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "server-100-system")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
			.put(Attribute.ATTRIBUTE_FORM_KEY_LISTENER, new InputKeyListener(ActionConstant.ACTION_SERVER_FILE_NAME, serverName, serverPort))
		), null, null);
		JPanel serverNamePanel=PanelFactory.create(Color.WHITE, null, new FlowLayout(FlowLayout.LEFT));
		serverNamePanel.add(serverName);
		serverNamePanel.add(LabelFactory.create(Attribute.create().put(Attribute.ATTRIBUTE_LABEL_TEXT, "-server")));
		
		FormFactory.addRow(form, 5, "微服务名称：", serverNamePanel, null, null);
		FormFactory.addRow(form, 6, "微服务端口：", serverPort, null, null);
		FormFactory.addRow(form, 7, "微服务中文名称：", serverComment=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_SERVER_COMMENT), ""))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "系统功能微服务")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		FormFactory.addRow(form, 8, "作者：", username=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_AUTHOR), SystemUtils.getSystemName()))
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "宇燕")
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				), null, null);
		serverMain.add(ScrollFactory.addScroll(form, null, null), BorderLayout.CENTER);
		QuickApplication.cache.setHash("server", "projectPath", projectPath.getComponent(0));
		QuickApplication.cache.setHash("server", "projectDomain", projectDomain);
		QuickApplication.cache.setHash("server", "nacosServer", nacosServer);
		QuickApplication.cache.setHash("server", "nacosNamespace", nacosNamespace);
		QuickApplication.cache.setHash("server", "serverFileName", serverFileName);
		QuickApplication.cache.setHash("server", "serverName", serverName);
		QuickApplication.cache.setHash("server", "serverPort", serverPort);
		QuickApplication.cache.setHash("server", "serverComment", serverComment);
		QuickApplication.cache.setHash("server", "username", username);
		
		JPanel buttonPanel=PanelFactory.create(null, null, new FlowLayout(FlowLayout.CENTER));
		buttonPanel.add(ButtonFactory.createButton(Attribute.create()
			.put(Attribute.ATTRIBUTE_BUTTON_NAME, "生成微服务")
			.put(Attribute.ATTRIBUTE_BUTTON_ORIGINAL, true)
			.put(Attribute.ATTRIBUTE_BUTTON_OPAQUE, true)
			.put(Attribute.ATTRIBUTE_BUTTON_PADDING, null)
			.put(Attribute.ATTRIBUTE_BUTTON_MARGIN, null)
			.put(Attribute.ATTRIBUTE_BUTTON_ACTION, ButtonConstant.ACTION_CREATE_SERVER)
		));
		serverMain.add(buttonPanel, BorderLayout.SOUTH);
		
		JPanel describePanel=PanelFactory.create(null, null, new BorderLayout());

		
		JSplitPane split = SplitFactory.create(JSplitPane.VERTICAL_SPLIT, serverMain, describePanel, 430, 2, false);
		serverFrame.add(split);
	}
	
	private void initCreateModuleFrame(JPanel createModuleFrame){
		JPanel tools=PanelFactory.create(Color.WHITE, BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(220, 220, 220)), new FlowLayout(FlowLayout.LEFT));
		createModuleFrame.add(tools, BorderLayout.NORTH);
		tools.add(ButtonFactory.createButton(Attribute.create()
			.put(Attribute.ATTRIBUTE_BUTTON_NAME, "数据库链接")
			.put(Attribute.ATTRIBUTE_BUTTON_ORIGINAL, true)
			.put(Attribute.ATTRIBUTE_BUTTON_OPAQUE, true)
			.put(Attribute.ATTRIBUTE_BUTTON_PADDING, null)
			.put(Attribute.ATTRIBUTE_BUTTON_MARGIN, null)
			.put(Attribute.ATTRIBUTE_BUTTON_ACTION, ButtonConstant.ACTION_CONNECTION_DATABASE)
		));
		tools.add(ButtonFactory.createButton(Attribute.create()
			.put(Attribute.ATTRIBUTE_BUTTON_NAME, "生成路径配置")
			.put(Attribute.ATTRIBUTE_BUTTON_ORIGINAL, true)
			.put(Attribute.ATTRIBUTE_BUTTON_OPAQUE, true)
			.put(Attribute.ATTRIBUTE_BUTTON_PADDING, null)
			.put(Attribute.ATTRIBUTE_BUTTON_MARGIN, null)
			.put(Attribute.ATTRIBUTE_BUTTON_ACTION, ButtonConstant.ACTION_GENERICS_PATH_CONFIG)
		));
		tools.add(LabelFactory.create(Attribute.create().put(Attribute.ATTRIBUTE_LABEL_TEXT, "数据库：")));
		String driver=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_DRIVER);
		String url=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_URL);
		List<String> databaseList=new ArrayList<String>();
		boolean isDatabaseConnection=false;
		if(ObjectUtils.isNotEmpty(driver) && ObjectUtils.isNotEmpty(url)){
			isDatabaseConnection=true;
			String username=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_USERNAME);
			String password=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_PASSWORD);
			try {
				DbSession.setInstance(driver, url, username, password);
				DbSession.find("show databases", new FindDataBack() {
					private String[] exclude = QuickApplication.getConfig(QuickConstant.CONF_DATABASE_EXCLUDE).split("\\,");
					public boolean handleRow(Map<String, Object> rowData, int row){
						String databaseName=(String)rowData.get("Database");
						if(ObjectUtils.contains(exclude, databaseName)){
							return true;
						}
						databaseList.add(databaseName);
						return true;
					};
				});
			} catch (Exception e) {
				isDatabaseConnection=false;
				MessageFactory.error(this, "无法链接数据库："+url);
			}
		}
		String defaultDatabase=QuickApplication.getConfig(QuickConstant.CONF_DEFAULT_DATABASE);
		if(ObjectUtils.isEmpty(defaultDatabase) && ObjectUtils.isNotEmpty(databaseList)){
			defaultDatabase=databaseList.get(0);
		}
		JComboBox<String> databaseSelect = FormFactory.createFormSelect(Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_SELECT_OPTIONS, databaseList.toArray())
			.put(Attribute.ATTRIBUTE_FORM_HEIGHT_AUTO, true)
			.put(Attribute.ATTRIBUTE_FORM_VALUE, defaultDatabase)
			.put(Attribute.ATTRIBUTE_FORM_SELECT_LISTENER, new ItemListener() {
				@Override
				public void itemStateChanged(ItemEvent e) {
					refreshDatabaseTable(e);
				}
			})
		);
		QuickApplication.cache.set(QuickConstant.CACHE_MODULE_DATABASE, databaseSelect);
		tools.add(databaseSelect);
		tools.add(ButtonFactory.createButton(Attribute.create()
			.put(Attribute.ATTRIBUTE_BUTTON_NAME, "生成代码")
			.put(Attribute.ATTRIBUTE_BUTTON_ORIGINAL, true)
			.put(Attribute.ATTRIBUTE_BUTTON_OPAQUE, true)
			.put(Attribute.ATTRIBUTE_BUTTON_PADDING, null)
			.put(Attribute.ATTRIBUTE_BUTTON_MARGIN, null)
			.put(Attribute.ATTRIBUTE_BUTTON_ACTION, ButtonConstant.ACTION_GENERICS_MODULE)
		));
		
		
		JPanel tablePanel=PanelFactory.create(Color.WHITE, null, new BorderLayout());
		createModuleFrame.add(tablePanel, BorderLayout.CENTER);
		TableTitle[] titles=new TableTitle[9];
		titles[0]=new TableTitle(" ", false, 15, 15, null);
		titles[1]=new TableTitle("表名", false, 300, null, null);
		titles[2]=new TableTitle("描述", false, 300, null, null);
		titles[3]=new TableTitle("所属服务", true, 150, null, null);
		titles[4]=new TableTitle("所属模块", true, 150, null, null);
		titles[5]=new TableTitle("业务子模块", true, 150, null, null);
		titles[6]=new TableTitle("数据子模块", true, 150, null, null);
		titles[7]=new TableTitle("生成模块", true, 300, null, null);
		titles[8]=new TableTitle("功能", true, 300, null, null);
		List<Object[]> dataList=new ArrayList<Object[]>(); 
		if(ObjectUtils.isNotEmpty(defaultDatabase) && isDatabaseConnection){
			getDatabaseTableList(defaultDatabase, dataList);
		}
		Table table = TableFactory.create(titles, dataList.toArray(new Object[dataList.size()][]), "tableList");
		QuickApplication.cache.set(QuickConstant.CACHE_MODULE_TABLE, table);
		tablePanel.add(ScrollFactory.addScroll(table, null, null));
	}
	
	private void refreshDatabaseTable(ItemEvent e) {
		String database=(String)e.getItem();
		Table table = QuickApplication.cache.get(QuickConstant.CACHE_MODULE_TABLE);
		TableFactory.deleteAll(table);
		String floors=QuickApplication.getConfig(QuickConstant.CONF_GENERICS_MODULE_FLOORS);
		String operator=QuickApplication.getConfig(QuickConstant.CONF_GENERICS_MODULE_OPERATORS);
		DbSession.find("select table_name name,table_comment `comment` from information_schema.tables t where table_schema=? and LOWER(table_type)='base table' order by create_time desc", new FindDataBack() {
			@Override
			public boolean handleRow(Map<String, Object> rowData, int row) {
				String tableName = (String)rowData.get("name");
				int index=tableName.indexOf("_");
				String module=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".module");
				String currModule=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".currModule");
				String businessModule=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".businessModule");
				String genericsModule=ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".genericsModule"), floors);
				String dataOperator=ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".dataOperator"), operator);
				String server=ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".server"), "");
				String override=ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".override"), "否");
				if(index!=-1 && ObjectUtils.isEmpty(currModule)){
					module=tableName.substring(0, index);
					if(tableName.charAt(tableName.length()-1)=='_'){
						tableName=tableName.substring(0, tableName.length()-1);
					}
					currModule=tableName.substring(index+1).replace("_", ".");
				}
				TableFactory.addRowData(table, new Object[]{"", rowData.get("name"), ObjectUtils.init(rowData.get("comment"), ""), server, module, businessModule, currModule, genericsModule, dataOperator, override});
				return super.handleRow(rowData, row);
			}
		}, database);
	}
	
	private void refreshDatabaseTableAddField(ItemEvent e) {
		String database=(String)e.getItem();
		JComboBox<String> tableSelect=QuickApplication.cache.getHash("addField", "table");
		tableSelect.removeAllItems();
		DbSession.find("select table_name name,table_comment `comment` from information_schema.tables t where table_schema=? and LOWER(table_type)='base table' order by create_time desc", new FindDataBack() {
			@Override
			public boolean handleRow(Map<String, Object> rowData, int row) {
				String tableName = (String)rowData.get("name");
				tableSelect.addItem(tableName+"("+ObjectUtils.init(rowData.get("comment"), "")+")");
				return super.handleRow(rowData, row);
			}
		}, database);
		refreshTableAddField((String)tableSelect.getSelectedItem());
	}
	
	private void refreshTableAddField(String tableName) {
		JComboBox<String> databaseSelect=QuickApplication.cache.getHash("addField", "database");
		String database=(String)databaseSelect.getSelectedItem();
		String moduleText=null;
		String currModuleText=null;
		if(ObjectUtils.isNotEmpty(tableName)) {
			tableName=tableName.substring(0, tableName.indexOf("("));
			currModuleText=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".currModule");
			moduleText=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".module");
			int index=tableName.indexOf("_");
			if(index!=-1 && ObjectUtils.isEmpty(currModuleText)){
				moduleText=tableName.substring(0, index);
				if(tableName.charAt(tableName.length()-1)=='_'){
					tableName=tableName.substring(0, tableName.length()-1);
				}
				currModuleText=tableName.substring(index+1).replace("_", ".");
			}
		}
		JTextField module=QuickApplication.cache.getHash("addField", "module");
		module.setText(moduleText);
		JTextField currModule=QuickApplication.cache.getHash("addField", "currModule");
		currModule.setText(currModuleText);
		JTextField fieldName=QuickApplication.cache.getHash("addField", "fieldName");
		fieldName.setText("");
		JTextField fieldLength=QuickApplication.cache.getHash("addField", "fieldLength");
		fieldLength.setText("");
		JTextField fieldScale=QuickApplication.cache.getHash("addField", "fieldScale");
		fieldScale.setText("");
	}
	
	private void refreshDatabaseTableDropField(ItemEvent e) {
		String database=(String)e.getItem();
		JComboBox<String> tableSelect=QuickApplication.cache.getHash("dropField", "table");
		tableSelect.removeAllItems();
		DbSession.find("select table_name name,table_comment `comment` from information_schema.tables t where table_schema=? and LOWER(table_type)='base table' order by create_time desc", new FindDataBack() {
			@Override
			public boolean handleRow(Map<String, Object> rowData, int row) {
				String tableName = (String)rowData.get("name");
				tableSelect.addItem(tableName+"("+ObjectUtils.init(rowData.get("comment"), "")+")");
				return super.handleRow(rowData, row);
			}
		}, database);
		refreshTableDropField((String)tableSelect.getSelectedItem());
	}
	
	private void refreshTableDropField(String tableName) {
		JComboBox<String> databaseSelect=QuickApplication.cache.getHash("dropField", "database");
		String database=(String)databaseSelect.getSelectedItem();
		String moduleText=null;
		String currModuleText=null;
		if(ObjectUtils.isNotEmpty(tableName)) {
			tableName=tableName.substring(0, tableName.indexOf("("));
			currModuleText=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".currModule");
			moduleText=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".module");
			int index=tableName.indexOf("_");
			if(index!=-1 && ObjectUtils.isEmpty(currModuleText)){
				moduleText=tableName.substring(0, index);
				if(tableName.charAt(tableName.length()-1)=='_'){
					tableName=tableName.substring(0, tableName.length()-1);
				}
				currModuleText=tableName.substring(index+1).replace("_", ".");
			}
		}
		JTextField module=QuickApplication.cache.getHash("dropField", "module");
		module.setText(moduleText);
		JTextField currModule=QuickApplication.cache.getHash("dropField", "currModule");
		currModule.setText(currModuleText);
		JTextField fieldName=QuickApplication.cache.getHash("dropField", "fieldName");
		fieldName.setText("");
	}
	
	public void refreshFieldType(String fieldType) {
		JTextField fieldLength=QuickApplication.cache.getHash("addField", "fieldLength");
		fieldLength.setText("");
		JTextField fieldScale=QuickApplication.cache.getHash("addField", "fieldScale");
		fieldScale.setText("");
		JTextField fieldValue=QuickApplication.cache.getHash("addField", "fieldValue");
		fieldValue.setText("");
		//bit,tinyint,int,integer,numeric,bigint,decimal,float,double,date,time,datetime,timestamp,char,varchar,text,longtext,geometry,geometrycollection,json,linestring,binary,blob,longblob,enum,mediumblob,
		//mediumint,mediumtext,multilinestring,multipoint,multipolygon,point,polygon,real,set,smallint,tinyblob,tinytext,varbinary,year
		fieldValue.setEditable(false);
		if(fieldType.equals("bit") || fieldType.equals("char") || fieldType.equals("varchar") || fieldType.equals("tinyint") || fieldType.equals("int") || fieldType.equals("integer") || fieldType.equals("bigint")
				|| fieldType.equals("mediumint") || fieldType.equals("smallint") || fieldType.equals("binary") || fieldType.equals("varbinary")) {
			fieldLength.setEditable(true);
			fieldScale.setEditable(false);
		}else if(fieldType.equals("text") || fieldType.equals("longtext") || fieldType.equals("geometry") || fieldType.equals("geometrycollection") || fieldType.equals("json") || fieldType.equals("linestring")
				 || fieldType.equals("blob") || fieldType.equals("longblob") || fieldType.equals("mediumblob") || fieldType.equals("mediumtext") || fieldType.equals("multilinestring")
				 || fieldType.equals("multipoint") || fieldType.equals("multipolygon") || fieldType.equals("point") || fieldType.equals("polygon") || fieldType.equals("real") || fieldType.equals("tinyblob")
				 || fieldType.equals("tinytext") || fieldType.equals("year") || fieldType.equals("date") || fieldType.equals("time") || fieldType.equals("datetime") || fieldType.equals("timestamp")){
			fieldLength.setEditable(false);
			fieldScale.setEditable(false);
		}else if(fieldType.equals("numeric") || fieldType.equals("decimal") || fieldType.equals("float") || fieldType.equals("double")) {
			fieldLength.setEditable(true);
			fieldScale.setEditable(true);
		}else if(fieldType.equals("enum") || fieldType.equals("set")){
			fieldValue.setEditable(true);
			fieldLength.setEditable(false);
			fieldScale.setEditable(false);
		}
		JTextField fieldDefault=QuickApplication.cache.getHash("addField", "fieldDefault");
		fieldDefault.setText("");
	}

	private void getDatabaseTableList(String defaultDatabase, List<Object[]> dataList) {
		String database=defaultDatabase;
		String floors=QuickApplication.getConfig(QuickConstant.CONF_GENERICS_MODULE_FLOORS);
		String operator=QuickApplication.getConfig(QuickConstant.CONF_GENERICS_MODULE_OPERATORS);
		DbSession.find("select table_name name,table_comment `comment` from information_schema.tables t where table_schema=? and LOWER(table_type)='base table' order by create_time desc", new FindDataBack() {
			@Override
			public boolean handleRow(Map<String, Object> rowData, int row) {
				String tableName = (String)rowData.get("name");
				int index=tableName.indexOf("_");
				String module=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".module");
				String currModule=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".currModule");
				String businessModule=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".businessModule");
				String genericsModule=ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".genericsModule"), floors);
				String dataOperator=ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".dataOperator"), operator);
				String server=ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+database+"."+tableName+".server"), "");
				if(index!=-1 && ObjectUtils.isEmpty(currModule)){
					module=tableName.substring(0, index);
					if(tableName.charAt(tableName.length()-1)=='_'){
						tableName=tableName.substring(0, tableName.length()-1);
					}
					currModule=tableName.substring(index+1).replace("_", ".");
				}
				dataList.add(new Object[]{"", tableName, ObjectUtils.init(rowData.get("comment"), ""), server, module, businessModule, currModule, genericsModule, dataOperator});
				return super.handleRow(rowData, row);
			}
		}, defaultDatabase);
	}
	
	private void getDatabaseTableListForAddField(String defaultDatabase, List<String> dataList) {
		DbSession.find("select table_name name,table_comment `comment` from information_schema.tables t where table_schema=? and LOWER(table_type)='base table' order by create_time desc", new FindDataBack() {
			@Override
			public boolean handleRow(Map<String, Object> rowData, int row) {
				String tableName = (String)rowData.get("name");
				dataList.add(tableName+"("+ObjectUtils.init(rowData.get("comment"), "")+")");
				return super.handleRow(rowData, row);
			}
		}, defaultDatabase);
	}
	
	private void getDatabaseTableListForDropField(String defaultDatabase, List<String> dataList) {
		DbSession.find("select table_name name,table_comment `comment` from information_schema.tables t where table_schema=? and LOWER(table_type)='base table' order by create_time desc", new FindDataBack() {
			@Override
			public boolean handleRow(Map<String, Object> rowData, int row) {
				String tableName = (String)rowData.get("name");
				dataList.add(tableName+"("+ObjectUtils.init(rowData.get("comment"), "")+")");
				return super.handleRow(rowData, row);
			}
		}, defaultDatabase);
	}
	
	private void initAddFieldFrame(JPanel addFieldFrame){
		JPanel tools=PanelFactory.create(Color.WHITE, BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(220, 220, 220)), new FlowLayout(FlowLayout.LEFT));
		addFieldFrame.add(tools, BorderLayout.NORTH);
		tools.add(ButtonFactory.createButton(Attribute.create()
			.put(Attribute.ATTRIBUTE_BUTTON_NAME, "数据库链接")
			.put(Attribute.ATTRIBUTE_BUTTON_ORIGINAL, true)
			.put(Attribute.ATTRIBUTE_BUTTON_OPAQUE, true)
			.put(Attribute.ATTRIBUTE_BUTTON_PADDING, null)
			.put(Attribute.ATTRIBUTE_BUTTON_MARGIN, null)
			.put(Attribute.ATTRIBUTE_BUTTON_ACTION, ButtonConstant.ACTION_CONNECTION_DATABASE_ADD_FIELD)
		));
		tools.add(LabelFactory.create(Attribute.create().put(Attribute.ATTRIBUTE_LABEL_TEXT, "数据库：")));
		String driver=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_DRIVER);
		String url=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_URL);
		List<String> databaseList=new ArrayList<String>();
		boolean isDatabaseConnection=false;
		if(ObjectUtils.isNotEmpty(driver) && ObjectUtils.isNotEmpty(url)){
			isDatabaseConnection=true;
			String username=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_USERNAME);
			String password=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_PASSWORD);
			try {
				DbSession.setInstance(driver, url, username, password);
				DbSession.find("show databases", new FindDataBack() {
					private String[] exclude = QuickApplication.getConfig(QuickConstant.CONF_DATABASE_EXCLUDE).split("\\,");
					public boolean handleRow(Map<String, Object> rowData, int row){
						String databaseName=(String)rowData.get("Database");
						if(ObjectUtils.contains(exclude, databaseName)){
							return true;
						}
						databaseList.add(databaseName);
						return true;
					};
				});
			} catch (Exception e) {
				isDatabaseConnection=false;
				MessageFactory.error(this, "无法链接数据库："+url);
			}
		}
		String defaultDatabase=QuickApplication.getConfig(QuickConstant.CONF_DEFAULT_DATABASE);
		if(ObjectUtils.isEmpty(defaultDatabase) && ObjectUtils.isNotEmpty(databaseList)){
			defaultDatabase=databaseList.get(0);
		}
		JComboBox<String> databaseSelect = FormFactory.createFormSelect(Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_SELECT_OPTIONS, databaseList.toArray())
			.put(Attribute.ATTRIBUTE_FORM_HEIGHT_AUTO, true)
			.put(Attribute.ATTRIBUTE_FORM_VALUE, defaultDatabase)
			.put(Attribute.ATTRIBUTE_FORM_SELECT_LISTENER, new ItemListener() {
				@Override
				public void itemStateChanged(ItemEvent e) {
					refreshDatabaseTableAddField(e);
				}
			})
		);
		QuickApplication.cache.set(QuickConstant.CACHE_ADD_FIELD_DATABASE, databaseSelect);
		tools.add(databaseSelect);
		tools.add(ButtonFactory.createButton(Attribute.create()
			.put(Attribute.ATTRIBUTE_BUTTON_NAME, "生成代码")
			.put(Attribute.ATTRIBUTE_BUTTON_ORIGINAL, true)
			.put(Attribute.ATTRIBUTE_BUTTON_OPAQUE, true)
			.put(Attribute.ATTRIBUTE_BUTTON_PADDING, null)
			.put(Attribute.ATTRIBUTE_BUTTON_MARGIN, null)
			.put(Attribute.ATTRIBUTE_BUTTON_ACTION, ButtonConstant.ACTION_ADD_FIELD)
		));
		
		List<String> tableList=new ArrayList<String>();
		if(ObjectUtils.isNotEmpty(defaultDatabase) && isDatabaseConnection) {
			getDatabaseTableListForAddField(defaultDatabase, tableList);
		}
		JTextField projectDomain=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_DOMAIN), ""))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "com.xxx.cloud")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		);
		
		JComboBox<String> tableSelect = FormFactory.createFormSelect(Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_SELECT_OPTIONS, tableList.toArray())
			.put(Attribute.ATTRIBUTE_FORM_HEIGHT_AUTO, true)
			.put(Attribute.ATTRIBUTE_FORM_SELECT_LISTENER, new ItemListener() {
				@Override
				public void itemStateChanged(ItemEvent e) {
					refreshTableAddField((String)e.getItem());
				}
			})
		);
		String tableName=null;
		if(tableList.size()>0) {
			tableName=tableList.get(0);
		}
		JTextField pojoName,mapperName;
		JPanel form=FormFactory.create(Color.WHITE, null, 2, 15, null);
		FormFactory.addRow(form, 0, "项目路径：", FormFactory.createFormFile(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, FileChooseFactory.getDefaultFile().getAbsolutePath()+"\\")
				.put(Attribute.ATTRIBUTE_FORM_EDITABLE, false)
				.put(Attribute.ATTRIBUTE_FILECHOOSE_TYPE, JFileChooser.DIRECTORIES_ONLY)
				.put(Attribute.ATTRIBUTE_FILECHOOSE_ENABLED, false)
				.put(Attribute.ATTRIBUTE_FORM_ACTION, ButtonConstant.ACTION_CREATE_PROJECT_PATH_FILE_SELECT)
		), null, null);
		
		FormFactory.addRow(form, 1, "域名：", projectDomain, null, null);
		FormFactory.addRow(form, 2, "Pojo路径：", pojoName=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_POJO), "cloud-010-pojo"))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "cloud-010-pojo")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		FormFactory.addRow(form, 3, "Mapper路径：", mapperName=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_MAPPER), "cloud-015-mapper"))
			.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "cloud-015-mapper")
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		
		FormFactory.addRow(form, 4, "表名称：", tableSelect, null, null);
		String moduleText=null;
		String currModuleText=null;
		if(ObjectUtils.isNotEmpty(tableName)) {
			tableName=tableName.substring(0, tableName.indexOf("("));
			currModuleText=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+defaultDatabase+"."+tableName+".currModule");
			moduleText=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+defaultDatabase+"."+tableName+".module");
			int index=tableName.indexOf("_");
			if(index!=-1 && ObjectUtils.isEmpty(currModuleText)){
				moduleText=tableName.substring(0, index);
				if(tableName.charAt(tableName.length()-1)=='_'){
					tableName=tableName.substring(0, tableName.length()-1);
				}
				currModuleText=tableName.substring(index+1).replace("_", ".");
			}
		}
		JTextField module;
		FormFactory.addRow(form, 5, "所属模块：", module=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, moduleText)
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		JTextField currModule;
		FormFactory.addRow(form, 6, "当前模块：", currModule=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_VALUE, currModuleText)
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		JTextField fieldName;
		FormFactory.addRow(form, 7, "字段名称：", fieldName=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		JTextField fieldCommemt;
		FormFactory.addRow(form, 8, "字段描述：", fieldCommemt=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		String[] fieldTypeOptions=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_FIELD_TYPE).split("\\,");
		JComboBox<String> fieldType = FormFactory.createFormSelect(Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_SELECT_OPTIONS, ObjectUtils.asList(fieldTypeOptions).toArray())
			.put(Attribute.ATTRIBUTE_FORM_HEIGHT_AUTO, true)
			.put(Attribute.ATTRIBUTE_FORM_SELECT_LISTENER, new ItemListener() {
				@Override
				public void itemStateChanged(ItemEvent e) {
					refreshFieldType((String)e.getItem());
				}
			})
		);
		FormFactory.addRow(form, 9, "字段类型：", fieldType, null, null);
		JTextField fieldLength;
		FormFactory.addRow(form, 10, "字段长度：", fieldLength=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		JTextField fieldScale;
		FormFactory.addRow(form, 11, "字段精度：", fieldScale=FormFactory.createFormInput(
			Attribute.create()
			.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
		), null, null);
		JTextField fieldValue;
		FormFactory.addRow(form, 12, "字段枚举值：", fieldValue=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER,  "枚举类型时使用，多个用‘,’隔开")
				), null, null);
		JTextField fieldDefault;
		FormFactory.addRow(form, 13, "默认值：", fieldDefault=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				), null, null);
		JTextField insertAfter;
		FormFactory.addRow(form, 14, "字段位置（插入A字段之后）：", insertAfter=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER,  "数据库字段，将插入到此字段之后，为空则放在末尾")
				), null, null);
		
		String fieldTypeText=(String)fieldType.getSelectedItem();
		fieldValue.setEditable(false);
		if(fieldTypeText.equals("bit") || fieldTypeText.equals("char") || fieldTypeText.equals("varchar") || fieldTypeText.equals("tinyint") || fieldTypeText.equals("int") || fieldTypeText.equals("integer") || fieldTypeText.equals("bigint")
				|| fieldTypeText.equals("mediumint") || fieldTypeText.equals("smallint") || fieldTypeText.equals("binary") || fieldTypeText.equals("varbinary")) {
			fieldLength.setEditable(true);
			fieldScale.setEditable(false);
		}else if(fieldTypeText.equals("text") || fieldTypeText.equals("longtext") || fieldTypeText.equals("geometry") || fieldTypeText.equals("geometrycollection") || fieldTypeText.equals("json") || fieldTypeText.equals("linestring")
				 || fieldTypeText.equals("blob") || fieldTypeText.equals("longblob") || fieldTypeText.equals("mediumblob") || fieldTypeText.equals("mediumtext") || fieldTypeText.equals("multilinestring")
				 || fieldTypeText.equals("multipoint") || fieldTypeText.equals("multipolygon") || fieldTypeText.equals("point") || fieldTypeText.equals("polygon") || fieldTypeText.equals("real") || fieldTypeText.equals("tinyblob")
				 || fieldTypeText.equals("tinytext") || fieldTypeText.equals("year") || fieldTypeText.equals("date") || fieldTypeText.equals("time") || fieldTypeText.equals("datetime") || fieldTypeText.equals("timestamp")){
			fieldLength.setEditable(false);
			fieldScale.setEditable(false);
		}else if(fieldTypeText.equals("numeric") || fieldTypeText.equals("decimal") || fieldTypeText.equals("float") || fieldTypeText.equals("double")) {
			fieldLength.setEditable(true);
			fieldScale.setEditable(true);
		}else if(fieldTypeText.equals("enum") || fieldTypeText.equals("set")){
			fieldValue.setEditable(true);
			fieldLength.setEditable(false);
			fieldScale.setEditable(false);
		}
		
		addFieldFrame.add(ScrollFactory.addScroll(form, null, null), BorderLayout.CENTER);
		QuickApplication.cache.setHash("addField", "projectDomain", projectDomain);
		QuickApplication.cache.setHash("addField", "pojoName", pojoName);
		QuickApplication.cache.setHash("addField", "mapperName", mapperName);
		QuickApplication.cache.setHash("addField", "database", databaseSelect);
		QuickApplication.cache.setHash("addField", "table", tableSelect);
		QuickApplication.cache.setHash("addField", "module", module);
		QuickApplication.cache.setHash("addField", "currModule", currModule);
		QuickApplication.cache.setHash("addField", "fieldName", fieldName);
		QuickApplication.cache.setHash("addField", "fieldComment", fieldCommemt);
		QuickApplication.cache.setHash("addField", "fieldType", fieldType);
		QuickApplication.cache.setHash("addField", "fieldLength", fieldLength);
		QuickApplication.cache.setHash("addField", "fieldScale", fieldScale);
		QuickApplication.cache.setHash("addField", "fieldValue", fieldValue);
		QuickApplication.cache.setHash("addField", "fieldDefault", fieldDefault);
		QuickApplication.cache.setHash("addField", "insertAfter", insertAfter);
	}
	
	private void initDropFieldFrame(JPanel dropFieldFrame){
		JPanel tools=PanelFactory.create(Color.WHITE, BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(220, 220, 220)), new FlowLayout(FlowLayout.LEFT));
		dropFieldFrame.add(tools, BorderLayout.NORTH);
		tools.add(ButtonFactory.createButton(Attribute.create()
				.put(Attribute.ATTRIBUTE_BUTTON_NAME, "数据库链接")
				.put(Attribute.ATTRIBUTE_BUTTON_ORIGINAL, true)
				.put(Attribute.ATTRIBUTE_BUTTON_OPAQUE, true)
				.put(Attribute.ATTRIBUTE_BUTTON_PADDING, null)
				.put(Attribute.ATTRIBUTE_BUTTON_MARGIN, null)
				.put(Attribute.ATTRIBUTE_BUTTON_ACTION, ButtonConstant.ACTION_CONNECTION_DATABASE_DROP_FIELD)
				));
		tools.add(LabelFactory.create(Attribute.create().put(Attribute.ATTRIBUTE_LABEL_TEXT, "数据库：")));
		String driver=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_DRIVER);
		String url=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_URL);
		List<String> databaseList=new ArrayList<String>();
		boolean isDatabaseConnection=false;
		if(ObjectUtils.isNotEmpty(driver) && ObjectUtils.isNotEmpty(url)){
			isDatabaseConnection=true;
			String username=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_USERNAME);
			String password=QuickApplication.getConfig(QuickConstant.CONF_DATABASE_JDBC_PASSWORD);
			try {
				DbSession.setInstance(driver, url, username, password);
				DbSession.find("show databases", new FindDataBack() {
					private String[] exclude = QuickApplication.getConfig(QuickConstant.CONF_DATABASE_EXCLUDE).split("\\,");
					public boolean handleRow(Map<String, Object> rowData, int row){
						String databaseName=(String)rowData.get("Database");
						if(ObjectUtils.contains(exclude, databaseName)){
							return true;
						}
						databaseList.add(databaseName);
						return true;
					};
				});
			} catch (Exception e) {
				isDatabaseConnection=false;
				MessageFactory.error(this, "无法链接数据库："+url);
			}
		}
		String defaultDatabase=QuickApplication.getConfig(QuickConstant.CONF_DEFAULT_DATABASE);
		if(ObjectUtils.isEmpty(defaultDatabase) && ObjectUtils.isNotEmpty(databaseList)){
			defaultDatabase=databaseList.get(0);
		}
		JComboBox<String> databaseSelect = FormFactory.createFormSelect(Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_SELECT_OPTIONS, databaseList.toArray())
				.put(Attribute.ATTRIBUTE_FORM_HEIGHT_AUTO, true)
				.put(Attribute.ATTRIBUTE_FORM_VALUE, defaultDatabase)
				.put(Attribute.ATTRIBUTE_FORM_SELECT_LISTENER, new ItemListener() {
					@Override
					public void itemStateChanged(ItemEvent e) {
						refreshDatabaseTableDropField(e);
					}
				})
				);
		QuickApplication.cache.set(QuickConstant.CACHE_ADD_FIELD_DATABASE, databaseSelect);
		tools.add(databaseSelect);
		tools.add(ButtonFactory.createButton(Attribute.create()
				.put(Attribute.ATTRIBUTE_BUTTON_NAME, "删除代码")
				.put(Attribute.ATTRIBUTE_BUTTON_ORIGINAL, true)
				.put(Attribute.ATTRIBUTE_BUTTON_OPAQUE, true)
				.put(Attribute.ATTRIBUTE_BUTTON_PADDING, null)
				.put(Attribute.ATTRIBUTE_BUTTON_MARGIN, null)
				.put(Attribute.ATTRIBUTE_BUTTON_ACTION, ButtonConstant.ACTION_DROP_FIELD)
				));
		
		List<String> tableList=new ArrayList<String>();
		if(ObjectUtils.isNotEmpty(defaultDatabase) && isDatabaseConnection) {
			getDatabaseTableListForDropField(defaultDatabase, tableList);
		}
		JTextField projectDomain=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_DOMAIN), ""))
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "com.xxx.cloud")
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				);
		
		JComboBox<String> tableSelect = FormFactory.createFormSelect(Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_SELECT_OPTIONS, tableList.toArray())
				.put(Attribute.ATTRIBUTE_FORM_HEIGHT_AUTO, true)
				.put(Attribute.ATTRIBUTE_FORM_SELECT_LISTENER, new ItemListener() {
					@Override
					public void itemStateChanged(ItemEvent e) {
						refreshTableDropField((String)e.getItem());
					}
				})
				);
		String tableName=null;
		if(tableList.size()>0) {
			tableName=tableList.get(0);
		}
		JTextField pojoName,mapperName;
		JPanel form=FormFactory.create(Color.WHITE, null, 2, 15, null);
		FormFactory.addRow(form, 0, "项目路径：", FormFactory.createFormFile(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, FileChooseFactory.getDefaultFile().getAbsolutePath()+"\\")
				.put(Attribute.ATTRIBUTE_FORM_EDITABLE, false)
				.put(Attribute.ATTRIBUTE_FILECHOOSE_TYPE, JFileChooser.DIRECTORIES_ONLY)
				.put(Attribute.ATTRIBUTE_FILECHOOSE_ENABLED, false)
				.put(Attribute.ATTRIBUTE_FORM_ACTION, ButtonConstant.ACTION_CREATE_PROJECT_PATH_FILE_SELECT)
				), null, null);
		
		FormFactory.addRow(form, 1, "域名：", projectDomain, null, null);
		FormFactory.addRow(form, 2, "Pojo路径：", pojoName=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_POJO), "cloud-010-pojo"))
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "cloud-010-pojo")
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				), null, null);
		FormFactory.addRow(form, 3, "Mapper路径：", mapperName=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, ObjectUtils.init(QuickApplication.getConfig(QuickConstant.CONF_PROJECT_MAPPER), "cloud-015-mapper"))
				.put(Attribute.ATTRIBUTE_FORM_PLACEHOLDER, "cloud-015-mapper")
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				), null, null);
		
		FormFactory.addRow(form, 4, "表名称：", tableSelect, null, null);
		String moduleText=null;
		String currModuleText=null;
		if(ObjectUtils.isNotEmpty(tableName)) {
			tableName=tableName.substring(0, tableName.indexOf("("));
			currModuleText=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+defaultDatabase+"."+tableName+".currModule");
			moduleText=QuickApplication.getConfig(QuickConstant.CONF_POJO_TABLE_GENERICS_CONFIG+defaultDatabase+"."+tableName+".module");
			int index=tableName.indexOf("_");
			if(index!=-1 && ObjectUtils.isEmpty(currModuleText)){
				moduleText=tableName.substring(0, index);
				if(tableName.charAt(tableName.length()-1)=='_'){
					tableName=tableName.substring(0, tableName.length()-1);
				}
				currModuleText=tableName.substring(index+1).replace("_", ".");
			}
		}
		JTextField module;
		FormFactory.addRow(form, 5, "所属模块：", module=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, moduleText)
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				), null, null);
		JTextField currModule;
		FormFactory.addRow(form, 6, "当前模块：", currModule=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_VALUE, currModuleText)
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				), null, null);
		JTextField fieldName;
		FormFactory.addRow(form, 7, "字段名称：", fieldName=FormFactory.createFormInput(
				Attribute.create()
				.put(Attribute.ATTRIBUTE_FORM_MARGIN,  FormFactory.defaultMargin())
				), null, null);
		
		dropFieldFrame.add(ScrollFactory.addScroll(form, null, null), BorderLayout.CENTER);
		QuickApplication.cache.setHash("dropField", "projectDomain", projectDomain);
		QuickApplication.cache.setHash("dropField", "pojoName", pojoName);
		QuickApplication.cache.setHash("dropField", "mapperName", mapperName);
		QuickApplication.cache.setHash("dropField", "database", databaseSelect);
		QuickApplication.cache.setHash("dropField", "table", tableSelect);
		QuickApplication.cache.setHash("dropField", "module", module);
		QuickApplication.cache.setHash("dropField", "currModule", currModule);
		QuickApplication.cache.setHash("dropField", "fieldName", fieldName);
	}
	
	private void initBottom(JPanel bottom){
		JPanel left=PanelFactory.create(null, BorderFactory.createMatteBorder(0, 0, 0, 1, new Color(220, 220, 220)), new FlowLayout(FlowLayout.LEFT));
		Runtime runtime = Runtime.getRuntime();
		JLabel memory=LabelFactory.create(Attribute.create()
			.put(Attribute.ATTRIBUTE_LABEL_TEXT, "内存："+
					StringUtils.showCapacity(runtime.totalMemory()-runtime.freeMemory())+"/"+
					StringUtils.showCapacity(runtime.totalMemory())+"/"+
					StringUtils.showCapacity(runtime.maxMemory()))
			.put(Attribute.ATTRIBUTE_LABEL_ALIGN, JLabel.LEFT)
			.put(Attribute.ATTRIBUTE_LABEL_TIPS, "已使用/已分配/最大可分配")
		);
		left.add(memory);
		JLabel version=LabelFactory.create(Attribute.create()
			.put(Attribute.ATTRIBUTE_LABEL_TEXT, "，版本："+(String)QuickApplication.getConfig(QuickConstant.CONF_VERSION))
			.put(Attribute.ATTRIBUTE_LABEL_ALIGN, JLabel.LEFT)
		);
		left.add(version);
		
		bottom.add(left, BorderLayout.WEST);
		QuickApplication.cache.set(QuickConstant.CACHE_MEMORY_LABEL, memory);
		ThreadUtils.execute(new Runnable() {
			@Override
			public void run() {
				new Timer(5000, new MemoryTimerTask()).start();
			}
		});
		JPanel center=PanelFactory.create(null, null, new BorderLayout());
		JLabel centerLabel=LabelFactory.create(Attribute.create().put(Attribute.ATTRIBUTE_LABEL_TEXT, "").put(Attribute.ATTRIBUTE_LABEL_ALIGN, JLabel.LEFT));
		centerLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
		center.add(centerLabel);
		bottom.add(center, BorderLayout.CENTER);
		JPanel right=PanelFactory.create(null, BorderFactory.createMatteBorder(0, 1, 0, 0, new Color(220, 220, 220)), new FlowLayout(FlowLayout.LEFT));
		JLabel exeTime=LabelFactory.create(Attribute.create().put(Attribute.ATTRIBUTE_LABEL_TEXT, "执行时间：0秒").put(Attribute.ATTRIBUTE_LABEL_ALIGN, JLabel.LEFT));
		right.add(exeTime);
		bottom.add(right, BorderLayout.EAST);
		QuickApplication.setExeTimeLable(exeTime);
	}
	
	@Override
	public int getWidth() {
		return super.getWidth();
	}
	
	@Override
	public int getHeight() {
		return super.getHeight();
	}
	
}
